package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.client.ArticleFeign;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    @Lazy
    private IWmNewsService wmNewsService ;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService wmChannelService;

    @Autowired
    private IWmSensitiveService wmSensitiveService;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void audit(Integer id) {
        WmNews wmNews = wmNewsService.getById(id);
        audit(wmNews);
    }

    @Async
    @Override
    public void audit(WmNews wmNews) {

        System.out.println(Thread.currentThread().getName());

//        审核自管理的敏感词
        boolean isPass = checkSensitive(wmNews);
//        阿里云文本审核
       isPass = checkText(wmNews);
       if(!isPass) return;
//       文阿里云图片审核
        isPass = checkImages(wmNews);
        if(!isPass) return;

//       远程调用文章微服务创建app文章
//        判断是否达到发布时间      当前时间>=发布时间
//        System.currentTimeMillis();  //当前时间的毫秒值
//        wmNews.getPublishTime().getTime(); //发布时间的毫秒值
        if(System.currentTimeMillis()>=wmNews.getPublishTime().getTime()){
//            远程调用文章微服务生成一个app文章
            Long articleId = createApArticle(wmNews);
            wmNews.setArticleId(articleId);
//            0 草稿   1 提交（待审核）  2 审核失败   3 需要人工审核   4 人工审核通过    8 审核通过（待发布）            9 已发布
            wmNews.setStatus(9);
            wmNewsService.updateById(wmNews);
        }else{  // 都已经审核通过了，但是没有到发布时间
            wmNews.setStatus(8);
            wmNewsService.updateById(wmNews);

            //放延迟任务
            RBlockingDeque<Integer> rQueue = redissonClient.getBlockingDeque ("article-queue");
            RDelayedQueue<Integer> delayedQueue = redissonClient.getDelayedQueue (rQueue);

            //需要延迟的时间：发布时间-当前时间  单位毫秒
            long time = wmNews.getPublishTime ().getTime ()-System.currentTimeMillis ();
            delayedQueue.offer (wmNews.getId (),time, TimeUnit.MILLISECONDS);
        }

    }



    private boolean checkSensitive(WmNews wmNews) {
//        1、获取所有的敏感词
        List<WmSensitive> list = wmSensitiveService.list();
        List<String> stringList = list.stream().map(s -> s.getSensitives()).collect(Collectors.toList());
//        2、构建一个大Map
        SensitiveWordUtil.initMap(stringList);
//        3、使用MatchWords方法
        String text = wmNews.getTitle();
        String content = wmNews.getContent();
        List<ContentDto> contentDtoList = JSON.parseArray(content, ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }
        Map<String, Integer> integerMap = SensitiveWordUtil.matchWords(text);
        if(integerMap.size()!=0){ // 包含敏感词  {小额贷款=2, 随机随贷=1, 无抵押=1}
            wmNews.setStatus(2);   //2 审核失败
            String reason = String.join(",",integerMap.keySet());
            wmNews.setReason("自管理敏感词审核失败，原因是内容中包含："+reason); //审核失败的原因
            wmNewsService.updateById(wmNews);
            return false;
        }
        return true;
    }


    public Long createApArticle(WmNews wmNews) {

        ArticleDto articleDto = new ArticleDto();
        articleDto.setContent(wmNews.getContent());
//        articleDto.setId(); 雪花算法自动生成的
        articleDto.setTitle(wmNews.getTitle());

        articleDto.setAuthorId(wmNews.getUserId()); //自媒体文章作者
//        根据自媒体人id查询自媒体人对象，获取自媒体人的name
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        articleDto.setAuthorName(wmUser.getName());
        articleDto.setChannelId(wmNews.getChannelId());
//        根据频道的ID查询频道对象 获取频道名称
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType()); //部局 0  1  3
        articleDto.setFlag(0);  //文章标记            0 普通文章            1 热点文章            2 置顶文章            3 精品文章
        articleDto.setLabels(wmNews.getLabels());
        articleDto.setPublishTime(wmNews.getPublishTime());

//        wmNews.getImages(); // 自媒体文章封面图片
//        [{"id":256,"url":"http://192.168.85.143:9000/heima/32fbeafb-d6d3-4100-9b53-040fa4aab2cd.png"},
//        {"id":257,"url":"http://192.168.85.143:9000/heima/c289ae2a-89ea-4d3f-89a4-8b512db07645.png"},
//        {"id":258,"url":"http://192.168.85.143:9000/heima/a88f84e2-0678-42bf-8d55-d38ea450b454.png"}]
//        从自媒体文章图片中获取所有的url
        List<ImageDto> imageDtoList = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        List<String> urlList = imageDtoList.stream().map(imageDto -> imageDto.getUrl()).collect(Collectors.toList());

        articleDto.setImages(String.join(",",urlList)); //app文章的封面图片
//        http://192.168.85.143:9000/heima/f5697c17-180c-4b5c-af82-0fb5eb4eab85.jpeg,
//       http://192.168.85.143:9000/heima/3f9e7767-d01c-4f3d-a79d-522c6a70f7cc.png,
  //     http://192.168.85.143:9000/heima/5cd5a981-2cb6-46d0-a9da-a1a1fc2698d3.jpeg

        ResponseResult<Long> responseResult = articleFeign.saveApArticle(articleDto);
        if(responseResult.getCode()==0){
            return responseResult.getData();
        }else {
            throw new RuntimeException("远程调用失败");
        }
    }

    private boolean checkImages(WmNews wmNews) {

        try {
            List<String> imageUrlList = new ArrayList<>();// 存的是所有图片的url地址
    //        图片=文章内容图片+文章封面图片   需要去重的
            String images = wmNews.getImages();//文章封面图片 [{"id":255,"url":"http://192.168.85.143:9000/heima/50329970-e060-4e0e-8778-8ac2e9c09b44.jpeg"}]
            List<ImageDto> imageDtoList = JSON.parseArray(images, ImageDto.class);
            for (ImageDto imageDto : imageDtoList) {
                imageUrlList.add(imageDto.getUrl());
            }

    //        从文章内容中获取图片
            String content = wmNews.getContent();
            List<ContentDto> contentDtoList = JSON.parseArray(content, ContentDto.class);
            for (ContentDto contentDto : contentDtoList) {
                if (contentDto.getType().equals("image")) {
                    if(!imageUrlList.contains(contentDto.getValue())){  //判断是否已经存在，如果不存在才会添加到集合中
                         imageUrlList.add(contentDto.getValue());
                    }
                }
            }
    //        获取内容图片和封面图片的url地址（去重后的）

    //        根据地址从minio中下载图片
            List<byte[]> imageList = new ArrayList<>();
            for (String url : imageUrlList) {
                InputStream inputStream = minIOService.download(url);
    //           //        把每个文件转成字节数组
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }

//        阿里云审核


            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
//        suggestion: pass review block
            switch (suggestion){
                case "pass":{
                    return true;
                }
                case "review":{
                    //                0 草稿   1 提交（待审核）  2 审核失败   3 需要人工审核   4 人工审核通过    8 审核通过（待发布）            9 已发布
                    //                修改自媒体文章的状态
                    wmNews.setStatus(3);
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云图片审核需要人工审核，原因是："+label); //需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                }
                case "block":{
                    //                0 草稿   1 提交（待审核）  2 审核失败   3 需要人工审核   4 人工审核通过    8 审核通过（待发布）            9 已发布
                    //                修改自媒体文章的状态
                    wmNews.setStatus(2);
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云图片审核失败，原因是："+label); //需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

    }

    private boolean checkText(WmNews wmNews) {
//        提取自媒体文章中的文本：标题+文章内容中的文字

        String text = wmNews.getTitle();
        String content = wmNews.getContent();
        List<ContentDto> contentDtoList = JSON.parseArray(content, ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }

        try {
            Map map = greenTextScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
//        suggestion: pass review block
            switch (suggestion){
                case "pass":{
                    return true;
                }
                case "review":{
    //                0 草稿   1 提交（待审核）  2 审核失败   3 需要人工审核   4 人工审核通过    8 审核通过（待发布）            9 已发布
    //                修改自媒体文章的状态
                    wmNews.setStatus(3);
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云文本审核需要人工审核，原因是："+label); //需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                }
                case "block":{
    //                0 草稿   1 提交（待审核）  2 审核失败   3 需要人工审核   4 人工审核通过    8 审核通过（待发布）            9 已发布
    //                修改自媒体文章的状态
                    wmNews.setStatus(2);
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云文本审核失败，原因是："+label); //需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
